package com.quanyan.operative.main;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.RequestContextFilter;

import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.sql.DataSource;

/**
 * Created by zhang on 16/11/5.
 */
@Configuration
@ComponentScan(basePackages = {
        "com.quanyan.redisCluster.config",
        "com.quanyan.operative.service",
        "com.quanyan.operative.component",
        "com.quanyan.operative.mq",
        "com.quanyan.common.interceptor",    //参数校验拦截器, RequestBody, ResponseBody拦截. controllerAround拦截
        "com.quanyan.common.exception.handler", //全局异常捕获处理
        "com.quanyan.operative.web",
})
@EnableAutoConfiguration
@MapperScan(basePackages = {"com.quanyan.operative.mapper"})
@ImportResource({"classpath:spring/application-profile.xml"})
@EnableScheduling
public class Application {
    /**
     * 启动器
     * @param args
     */
    public static void main(String[] args){
        SpringApplication springApplication = new SpringApplication(Application.class);
        springApplication.run(args);
    }

    /**
     * 数据源配置
     * @return
     */
    @Bean(name = "dataSource", destroyMethod = "close", initMethod = "init")
    @ConfigurationProperties(prefix = "spring.datasource", locations = "classpath:application.properties")
    public DataSource dataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        return druidDataSource;
    }

    /**
     * mybatis配置
     * @return
     * @throws Exception
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource());
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/com/quanyan/operative/mapper/*.xml"));
        sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
        sqlSessionFactoryBean.setTypeAliasesPackage("");
        return sqlSessionFactoryBean.getObject();
    }

    /**
     * JDBC事务管理配置
     * @param datasource
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager(DataSource datasource){
        return new DataSourceTransactionManager(datasource);
    }

    /**
     * 字符格式化过滤器配置
     * @return
     */
    @Bean
    public Filter characterEncodingFilter(){
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        return characterEncodingFilter();
    }

    /**
     * 请求体上下文过滤器
     * @param servletContext
     * @return
     */
    @Bean
    public RequestContextFilter requestContextFilter(ServletContext servletContext){
        RequestContextFilter requestContextFilter = new RequestContextFilter();
        requestContextFilter.setServletContext(servletContext);
        requestContextFilter.setThreadContextInheritable(false);
        return requestContextFilter;
    }
}
